<template>
  <div class="content-wrap cycle-wrapper">
    <div class="content-box">
      <div :class="{ 'content-left w0': collapseIconLeft, 'content-left': !collapseIconLeft }">
        <div class="top-box">
          <Card>
            <div slot="title" class="tit">表具抄表周期统计直方图</div>
            <div class="bar-line-box">
              <h-bar3d :fetchData="getBarLineData" :chartData="seriesData" :defaultOptions="hBar3dOptions" />
              <div class="total-num">总表数:{{ meterTotal }}</div>
            </div>
          </Card>
        </div>
        <div class="bottom-box">
          <Card>
            <div slot="title" class="tit">抄表周期统计雷达图</div>
            <div class="bar-line-box">
              <e-radar :fetchData="getRadarData" :chartData="radarData" />
            </div>
          </Card>
        </div>
      </div>
      <div :class="centerClass">
        <Card>
          <div slot="title" class="filter-wrapper">
            <div class="collapse-left-icon collapse-icon" @click="collapseHandler('left')">
              <span v-if="collapseIconLeft" title="缩小">
                <Icon type="icon iconfont icon-xianghou" />
              </span>
              <span v-else title="放大">
                <Icon type="icon iconfont icon-xiangqian" />
              </span>
            </div>
            <Form slot="search-bar" inline ref="formCustom" style="text-align: center">
              <FormItem>
                <Dropdown trigger="custom" :visible="paramsFlag">
                  <Button type="info" @click="handleParams(true)" size="small">筛选条件</Button>
                  <DropdownMenu slot="list" class="fb params-setting" style="width: 400px;">
                    <DropdownItem style="display:flex;">
                      <div class="name">抄表周期</div>
                      <div class="slider">
                        <Slider :min="0" :max="1" :step="0.1" v-model="cycleNum"></Slider>
                      </div>
                      <span class="show-num">x {{ cycleNum }}</span>
                    </DropdownItem>
                    <DropdownItem>
                      <div class="name">大范围</div>
                      <div class="gas-range">
                        <div class="item">
                          <span class="name">用气量 &ge;</span>
                          <InputNumber :min="0" v-model="gasRange.maxGas" />
                        </div>
                        <div>
                          <span class="name">抄表周期 &ge;</span>
                          <InputNumber
                            :max="1"
                            :min="0"
                            :step="0.1"
                            type="number"
                            v-model="gasRange.maxCycle" />
                        </div>
                      </div>
                    </DropdownItem>
                    <DropdownItem>
                      <div class="name">小范围</div>
                      <div class="gas-range">
                        <div class="item">
                          <span class="name">用气量 &le;</span>
                          <InputNumber :min="0" v-model="gasRange.minGas" />
                        </div>
                        <div>
                          <span class="name">抄表周期 &le;</span>
                          <InputNumber
                            :max="1"
                            :min="0"
                            :step="0.1"
                            type="number"
                            v-model="gasRange.minCycle" />
                        </div>
                      </div>
                    </DropdownItem>
                    <div style="text-align: right;margin-right:16px;">
                      <Button @click="handleParams(false)" size="small" style="margin-right:5px;">关闭</Button>
                      <Button type="primary" @click="handleParamsSettingOk" size="small">确定</Button>
                    </div>
                  </DropdownMenu>
                </Dropdown>
              </FormItem>
            </Form>
            <div class="collapse-right-icon collapse-icon" @click="collapseHandler('right')">
              <span v-if="collapseIconRight" title="缩小">
                <Icon type="icon iconfont icon-xiangqian" />
              </span>
              <span v-else title="放大">
                <Icon type="icon iconfont icon-xianghou" />
              </span>
            </div>
          </div>
          <div class="chart-container">
            <div class="chart" key="effectScatter">
              <e-heatmap
                id="cycleScatterMap"
                :fetchData="getSdData"
                :chartData="eHeatmapData"
                :shrink="collapseIcon"
                @q-click="pointClickHandle"
              />
              <Spin fix v-show="eHeatmapLoading">地图规划中...</Spin>
            </div>
          </div>
        </Card>
      </div>
      <div :class="{ 'content-right w0': collapseIconRight, 'content-right': !collapseIconRight }">
        <div class="top-box">
          <Card>
            <div slot="title" class="tit clearfix">
              <span class="fl">流量/抄表周期散点图</span>
              <Select class="fr" placeholder="用气性质" size="small" v-model="sdGasClass" style="width: 100px;">
                <Option v-for="(type, index) in gasClassList" :key="index" :value="type.value">{{ type.value }}</Option>
              </Select>
            </div>
            <div class="bar-line-box">
              <div class="chart-box">
                <e-scatter
                  :chartData="sdData"
                  @q-click="pointClickHandle" />
              </div>
              <div class="sider-box">
                <Button type="primary" @click="handleShowTableClick" size="small">获取数据表格</Button>
              </div>
              <Spin fix v-show="sdLoading">加载中...</Spin>
            </div>
          </Card>
        </div>
        <div class="bottom-box">
          <Card>
            <div slot="title" class="tit">详情</div>
            <div class="detail-box">
              <meter-detail
                :currentMeterId="currentMeterId"
                :content="meterDetail"
                :columnNames="meterDetailColumns"
                :currentDate="currentDate"
              />
            </div>
          </Card>
        </div>
      </div>
      <Modal
        v-model="showTreemapTableModel"
        class="candlestick-modal"
        title="详情"
        @on-cancel="onTreemapTableCancel"
        width="96%"
        :styles="{ top: '30px', height: '85%' }"
      >
        <div :is="treemapTableTemplate" :options="treemapTaleOptions"></div>
        <div slot="footer">
          <Button @click="onTreemapTableCancel" ghost>关闭</Button>
        </div>
      </Modal>
      <!-- 表格下载 -->
      <Modal
        v-model="showDownTable"
        class="candlestick-modal"
        title="表格"
        width="96%"
        :styles="{ top: '30px'}"
      >
        <down-table v-if="showDownTable" :options="downTableOptions" />
      </Modal>
    </div>
  </div>
</template>
<script>
import dayjs from 'dayjs'
import { each, max, split, concat, reduce, merge, min } from 'lodash'
import { barLine, findList, radarInfo, meterDetail, meterGasClass } from '@/api/meterManageCycle'
import { eRadarOptions, hBar3dOptions, eScatterOptions, eHeatmapOptions } from './chartOptions/index'
import DownTable from './components/DownTable'
import meterDetailColumns from './meterDetailColumns'

export default {
  name: 'cycle',
  components: {
    DownTable,
    MeterDetail: () => import('@/commons/MeterDetail'),
    EHeatmap: () => import('@/commons/charts/EHeatmap'),
    HBar3d: () => import('@/commons/charts/HBar3d'),
    ERadar: () => import('@/commons/charts/ERadar'),
    EScatter: () => import('@/commons/charts/EScatter'),
    GasNatureTreemapAndTable: () => import('./components/GasNatureTreemapAndTable')
  },
  data() {
    return {
      paramsFlag: false,
      saveBtnLoading: false,
      chartsFlag: false,
      collapseIcon: false,
      collapseIconLeft: false,
      collapseIconRight: false,
      seriesData: null,
      eHeatmapData: null,
      eHeatmapList: [],
      sdData: null,
      sdList: [],
      radarData: null,
      cycleNum: 0,
      cycleNumBak: 0,
      meterDetail: {},
      centerPoint: null,
      currentMeterId: undefined,
      gasClassList: [],
      sdGasClass: 'CNG',
      showDetailLoading: false,
      detailComponent: null,
      showTreemapTableModel: false,
      treemapTableTemplate: null,
      treemapTaleOptions: {
        period: null
      },
      meterTotal: 0,
      eHeatmapLoading: false,
      sdLoading: false,
      gasRange: {
        maxGas: 3,
        maxCycle: 0.5,
        minGas: 1,
        minCycle: 0.5
      },
      showDownTable: false,
      downTableOptions: {}
    }
  },
  mounted() {
    this.centerPoint = this.$store.getters.mapCenter
    this.sliderListerMouseUp()
    this.getMeterGasClass()
  },
  watch: {
    sdGasClass() {
      this.getSdData({
        meterGasClass: this.sdGasClass
      })
    }
  },
  computed: {
    defaultDate() {
      return this.$config.nowDate
    },
    /**
     * @msg: 当前日期
     * @param {type}
     * @return:
     */
    currentDate() {
      return dayjs(this.defaultDate).format('YYYY-MM')
    },
    hBar3dOptions() {
      return hBar3dOptions
    },
    meterDetailColumns() {
      return meterDetailColumns
    },
    centerClass() {
      let _cls = 'content-center'
      if (this.collapseIconLeft) {
        _cls += ' l0'
      }
      if (this.collapseIconRight) {
        _cls += ' r0'
      }
      return _cls
    }
  },
  beforeDestroy() {
    document.removeEventListener('mouseup', this.handleMouseUp)
  },
  methods: {
    onTreemapTableCancel() {
      this.showTreemapTableModel = false
      this.treemapTableTemplate = null
    },
    /**
     * 两侧菜单收缩
     * @return {[type]} [description]
     */
    collapseHandler(direc) {
      const { collapseIconLeft, collapseIconRight, collapseIcon } = this
      if (direc === 'left') {
        this.collapseIconLeft = !collapseIconLeft
      } else {
        this.collapseIconRight = !collapseIconRight
      }
      this.collapseIcon = !collapseIcon
    },
    /**
     * @msg: 获取最大周期
     * @param {name} "0-1" "1-2" 类型的字符串
     * @return:
     */
    modifyNameMax(name) {
      const ret = split(name, '-')
      return ret
    },
    /**
     * 整理柱状图数据
     * @param  {[type]} data [description]
     * @return {[type]}      [description]
     */
    modifyBarLineData(data = []) {
      const _this = this
      const _xAxisList = []
      const _serList = []
      let nameMax = []
      each(data, item => {
        const { max, name } = item
        _xAxisList.push(name)
        _serList.push(max)
        const ret = this.modifyNameMax(name)
        nameMax = concat(nameMax, ret)
      })
      this.sliderMax = Number(max(nameMax))

      this.meterTotal = reduce(
        _serList,
        (sum, item) => {
          return sum + item
        },
        0
      )

      this.seriesData = merge({}, hBar3dOptions, {
        plotOptions: {
          series: {
            cursor: 'pointer',
            events: {
              click: function(e) {
                _this.barLineClickHandle(e, this)
              }
            }
          }
        },
        xAxis: {
          categories: _xAxisList
        },
        series: [
          {
            data: _serList
          }
        ]
      })
    },
    /**
     * desc: 获取闪点图坐标最大、最小值
     * param {type}
     * return: void
     */
    getEScatterMax(data = []) {
      const xArr = []
      const yArr = []
      each(data, item => {
        xArr.push(item[0])
        yArr.push(item[1])
      })

      const xMax = max(xArr)
      const xMin = min(xArr)
      const yMax = max(yArr)
      const yMin = min(yArr)

      return {
        xMax,
        xMin,
        yMax,
        yMin
      }
    },
    /**
     * @msg: 滑动条绑定鼠标松开事件
     * @param {type}
     * @return:
     */
    sliderListerMouseUp() {
      document.addEventListener('mouseup', this.handleMouseUp)
    },
    /**
     * desc: 滑动条鼠标松开
     * param {*}
     * return {*}
     */
    handleMouseUp() {
      if (Number(this.cycleNum) !== Number(this.cycleNumBak)) {
        this.cycleNumBak = this.cycleNum
        this.$nextTick(() => {
          this.modifyEHeatmapData(this.eHeatmapList)
          this.modifySdData(this.sdList)
        })
      }
    },
    /**
     * 点击参数设置
     * @param  {[type]} flag [description]
     * @return {[type]}      [description]
     */
    handleParams(flag) {
      this.paramsFlag = flag
    },
    /**
     * 获取柱状图数据
     * @return {[type]} [description]
     */
    getBarLineData() {
      barLine().then(res => {
        if (res.date && res.date.length >= 0) {
          this.modifyBarLineData(res.date)
        }
      })
    },
    async getSdData() {
      this.sdLoading = true
      this.eHeatmapLoading = true
      const { code, date } = await this.getChartData({
        meterGasClass: this.sdGasClass
      })
      this.sdLoading = false
      this.eHeatmapLoading = false
      if (code === 200) {
        this.sdList = date
        this.modifySdData(date)
        this.eHeatmapList = date
        this.modifyEHeatmapData(date)
      }
    },
    /**
     * 整理地图数据
     * @param  {[type]} data [description]
     * @return {[type]}      [description]
     */
    modifyEHeatmapData(data = []) {
      const _serList1 = []
      const _serList2 = []
      const { maxGas, maxCycle, minGas, minCycle } = this.gasRange
      each(data, item => {
        const { meterId, latitude, longitude, median, period, ...rest } = item
        if (period >= this.cycleNum) {
          if ((median >= maxGas && period >= maxCycle) || (median <= minGas && period <= minCycle)) {
            _serList2.push({
              name: meterId,
              value: [longitude, latitude, median],
              period,
              ...rest
            })
          } else {
            _serList1.push({
              name: meterId,
              value: [longitude, latitude, median],
              period,
              ...rest
            })
          }
        }
      })
      this.eHeatmapData = merge({}, eHeatmapOptions, {
        bmap: {
          center: this.centerPoint
        },
        series: [
          {
            data: _serList1
          },
          {
            data: _serList2
          }
        ]
      })
    },
    /**
     * desc: 整理闪点图数据
     * param {type}
     * return: void
     */
    modifySdData(data = []) {
      const _serList = []
      const _li = []
      each(data, item => {
        const { meterId, period, median, ...rest } = item
        if (period >= this.cycleNum) {
          const periodChart = [median, period]
          _serList.push({
            name: meterId,
            value: periodChart,
            ...rest
          })
          _li.push(periodChart)
        }
      })
      const { xMax = 0, xMin = 0, yMax = 0, yMin = 0 } = this.getEScatterMax(_li)
      const rangeAreaList = this.modifySdRangeAreaData(xMax, yMax)
      this.sdData = merge({}, eScatterOptions, {
        xAxis: {
          min: xMin,
          max: xMax
        },
        yAxis: {
          min: yMin,
          max: yMax
        },
        series: [
          {
            data: _serList
          },
          ...rangeAreaList
        ]
      })
    },
    modifySdRangeAreaData(xMax, yMax) {
      const { maxGas, maxCycle, minGas, minCycle } = this.gasRange
      const _lineStyle = {
        type: 'dotted',
        color: '#ff0000'
      }
      return [
        {
          type: 'line',
          data: [[0, minCycle], [minGas, minCycle], [minGas, 0]],
          lineStyle: _lineStyle,
          zlevel: 2
        },
        {
          type: 'line',
          data: [[maxGas, yMax], [maxGas, maxCycle], [xMax, maxCycle]],
          lineStyle: _lineStyle,
          zlevel: 2
        }
      ]
    },
    /**
     * 获取地图和散点图数据
     * 两个图形获取数据接口是一样的
     * @return {[type]} [description]
     */
    async getChartData(params) {
      const ret = await findList(params)
      return ret
    },
    /**
     * 获取用气性质
     * @return {[type]} [description]
     */
    getMeterGasClass() {
      meterGasClass()
        .then(res => {
          if (res.date && res.date.length >= 0) {
            this.gasClassList = res.date
          } else {
            this.gasClassList = []
          }
        })
        .catch(() => {
          this.gasClassList = []
        })
    },
    /**
     * @msg: 雷达图选中数据筛选
     * @param {type}
     * @return:
     */
    radarSelected(data) {
      let legendData = []
      const selectedData = {}
      each(data, item => {
        if (item === this.sdGasClass) {
          legendData = concat(item, legendData)
          selectedData[item] = true
        } else {
          legendData = concat(legendData, item)
          selectedData[item] = false
        }
      })

      return {
        legendData,
        selectedData
      }
    },
    /**
     * @msg: 雷达图legend字段
     * @param {type}
     * @return:
     */
    radarLegend(data) {
      const _legendList = []
      each(data, item => {
        _legendList.push(item.name)
      })

      return _legendList
    },
    /**
     * @msg: 整理雷达图数据
     * @param {type}
     * @return:
     */
    modifyRadarData(data) {
      const _legendList = this.radarLegend(data)
      const _serList = []
      each(data, item => {
        _serList.push({
          ...item,
          areaStyle: {
            opacity: 0.1
          }
        })
      })
      const { legendData, selectedData } = this.radarSelected(_legendList)
      return {
        legendData,
        selectedData,
        seriesData: _serList
      }
    },
    /**
     * 获取热力图数据
     * @return {[type]} [description]
     */
    getRadarData() {
      radarInfo().then(res => {
        const ret = res.date
        if (ret) {
          const { data, maxCountByLevel } = ret
          const { legendData, selectedData, seriesData } = this.modifyRadarData(data)

          this.radarData = merge({}, eRadarOptions, {
            tooltip: {
              formatter: function(val) {
                const { count } = val.data
                let str = ''
                each(maxCountByLevel, (item, index) => {
                  str += item.name + ':' + count[index] + '<br/>'
                })
                return str
              }
            },
            legend: {
              data: legendData,
              selected: selectedData
            },
            radar: {
              indicator: maxCountByLevel
            },
            series: [
              {
                data: seriesData
              }
            ]
          })
        }
      })
    },
    /**
     * @msg: 获取表具详情
     * @param {meterId} 表具id
     * @return:
     */
    getMeterDetail(meterId) {
      this.currentMeterId = meterId
      meterDetail(meterId).then(res => {
        if (res.date) {
          this.meterDetail = res.date
        }
      })
    },
    /**
     * @msg: 散点图表具点点击
     * @param {type}
     * @return:
     */
    pointClickHandle(data = {}) {
      const {
        data: { name }
      } = data
      if (name) {
        this.getMeterDetail(name)
      }
    },
    barLineClickHandle(data) {
      const period = data.point.category

      this.treemapTaleOptions = {
        ...this.treemapTaleOptions,
        period
      }
      this.showTreemapTableModel = true
      this.$nextTick(() => {
        this.treemapTableTemplate = 'GasNatureTreemapAndTable'
      })
    },
    handleParamsSettingOk() {
      const { maxGas, maxCycle, minGas, minCycle } = this.gasRange
      if (maxGas < minGas) {
        return this.$Notice.warning({
          title: '操作提示',
          desc: '大范围的用气量不能小于小范围用气量'
        })
      }
      if (maxCycle < minCycle) {
        return this.$Notice.warning({
          title: '操作提示',
          desc: '大范围的抄表周期不能小于小范围抄表周期'
        })
      }

      this.modifyEHeatmapData(this.eHeatmapList)
      this.modifySdData(this.sdList)
      this.handleParams(false)
    },
    handleShowTableClick() {
      this.downTableOptions.meterGasClass = this.sdGasClass
      this.showDownTable = true
    }
  }
}
</script>
<style scoped lang="less">
@import './index.less';
</style>
